#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "iostream"
#include "QDataStream"
#include "QtTypes"
#include "QDropEvent"
#include "QUrl"
#include "QFile"
#include <QtConcurrent>
#include <QFuture>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
    ui(new Ui::MainWindow),
    socket(new QWebSocket)
{
    setAcceptDrops(true);
    ui->setupUi(this);
    QObject::connect(ui->socketContactBtn, &QPushButton::clicked, this, &MainWindow::contactSocketServer);
    QObject::connect(ui->sendMessageBtn, &QPushButton::clicked, this, &MainWindow::sendTextMessage);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::dropEvent(QDropEvent *event)
{
    // 获取拖拽的数据
    const QMimeData *mimeData = event->mimeData();

    // 如果是文件拖拽
    if (mimeData->hasUrls()) {
        QList<QUrl> urlList = mimeData->urls();

        // 遍历所有拖拽的文件
        for (const QUrl &url : urlList) {
            QString filePath = url.toLocalFile();
            qDebug() << "文件路径:" << filePath;
            QFile file(filePath);

            if (!file.open(QIODevice::ReadOnly)) {
                qDebug() << "无法打开文件:" << filePath;
                return;
            }

            sendBinaryMessage(file);
        }
    }
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    // 检查拖拽的数据类型
    if (event->mimeData()->hasUrls()) {
        event->acceptProposedAction( ); // 接受这个拖拽事件
    }
}

void MainWindow::contactSocketServer()
{
    QUrl url = QUrl(ui->socketURL->text());

    if (url.isValid() && (url.scheme() == "ws" || url.scheme() == "wss")) {
        qDebug() << "Valid WebSocket URL";
        socket->open(url);
    } else {
        qDebug() << "Invalid WebSocket URL";
    }
}

void MainWindow::sendTextMessage()
{
    QString messageText = ui->messageInput->toPlainText();
    MessageData data;
    QByteArray message = messageText.toUtf8();

    data.flowType = MessageFlowType::text;
    data.lastFrame = MessageLastFrame::yes;
    data.data = message.constData();
    data.size = message.size();

    sendMessage(data);
}

void MainWindow::sendBinaryMessage(QFile &file)
{
    qint64 chunkSize = 10 * 1e3;
    qint64 bytesRead = 0;

    // 开启 新线程发送二进制消息
    QFuture<void> future = QtConcurrent::run([&]() {
        while(!file.atEnd()) {
            QByteArray chunk = file.read(chunkSize);
            if (!chunk.isEmpty()) {
                MessageData data;
                data.flowType = MessageFlowType::image;
                data.size = chunk.size();
                data.data = chunk.constData();
                bytesRead += chunk.size();
                data.lastFrame = bytesRead >= file.size() ? MessageLastFrame::yes : MessageLastFrame::no;

                sendMessage(data);
            }
        }

        file.close();
    });
}

void MainWindow::sendMessage(MessageData &data)
{
    QByteArray packet;
    QDataStream stream(&packet, QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::LittleEndian);

    stream << data.flowType << data.size << data.lastFrame;
    stream.writeRawData(data.data, data.size);

    socket->sendBinaryMessage(packet);
}
